home *** CD-ROM | disk | FTP | other *** search
- -- This file is part of SmallEiffel The GNU Eiffel Compiler.
- -- Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
- -- Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
- -- http://www.loria.fr/SmallEiffel
- -- SmallEiffel is free software; you can redistribute it and/or modify it
- -- under the terms of the GNU General Public License as published by the Free
- -- Software Foundation; either version 2, or (at your option) any later
- -- version. SmallEiffel is distributed in the hope that it will be useful,but
- -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- -- for more details. You should have received a copy of the GNU General
- -- Public License along with SmallEiffel; see the file COPYING. If not,
- -- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- -- Boston, MA 02111-1307, USA.
- --
- class EFFECTIVE_ARG_LIST
- --
- -- For an effective arguments list (for a routine call).
- --
-
- inherit
- GLOBALS
- redefine fill_tagged_out_memory
- end;
-
- creation make
-
- feature {EFFECTIVE_ARG_LIST}
-
- list: ARRAY[EXPRESSION];
- -- Corresponding list of actual arguments.
-
- feature
-
- current_type: TYPE;
- -- Not Void when checked in.
-
- feature
-
- make(l: like list) is
- require
- l.lower = 1;
- not l.empty;
- do
- list := l;
- ensure
- list = l
- end;
-
- feature
-
- fill_tagged_out_memory is
- local
- p: POSITION;
- ct: TYPE;
- rtm: STRING;
- do
- p := start_position;
- if p /= Void then
- p.fill_tagged_out_memory;
- end;
- ct := current_type;
- if ct /= Void then
- rtm := ct.run_time_mark;
- if rtm /= Void then
- tagged_out_memory.append(" ct=");
- tagged_out_memory.append(rtm);
- end;
- end;
- end;
-
- run_class: RUN_CLASS is
- do
- Result := current_type.run_class;
- end;
-
- start_position: POSITION is
- do
- Result := list.item(1).start_position;
- end;
-
- count: INTEGER is
- do
- Result := list.upper;
- end;
-
- expression(i: INTEGER): EXPRESSION is
- require
- 1 <= i;
- i <= count;
- do
- Result := list.item(i);
- ensure
- Result /= Void
- end;
-
- first: EXPRESSION is
- do
- Result := list.first;
- end;
-
- match_with(rf: RUN_FEATURE) is
- -- Check the good match for real/formal arguments.
- require
- rf /= Void;
- local
- fal: FORMAL_ARG_LIST;
- i: INTEGER;
- e: EXPRESSION;
- at, ft: TYPE;
- do
- fal := rf.arguments;
- if fal = Void then
- eh.add_position(rf.start_position);
- error(start_position,em2);
- end;
- if nb_errors = 0 and then fal.count /= count then
- eh.add_position(fal.start_position);
- error(start_position,em2);
- end;
- from
- i := list.upper;
- until
- i = 0 or else nb_errors > 0
- loop
- e := list.item(i);
- at := e.result_type;
- ft := fal.type(i);
- check
- at.is_run_type;
- ft.is_run_type;
- end;
- if e.is_void then
- if ft.is_expanded then
- eh.add_position(e.start_position);
- error(ft.start_position,
- "Cannot pass Void for expanded argument.");
- end;
- elseif ft.is_like_current then
- if e.is_current then
- elseif at.run_type.is_a(ft.run_type) then
- if at.run_type.is_expanded then
- elseif ft.run_type.is_a(at.run_type) then
- else
- eh.add_position(e.start_position);
- error(ft.start_position,em1);
- end;
- else
- eh.add_position(e.start_position);
- error(ft.start_position,em1);
- end;
- elseif ft.is_like_feature then
- if at.run_type.is_a(ft.run_type) then
- else
- eh.add_position(e.start_position);
- error(ft.start_position," It is not Like <feature>.");
- end;
- elseif is_like_argument(e,at,ft) then
- elseif at.run_type.is_a(ft.run_type) then
- else
- eh.print_as_error;
- eh.add_position(ft.start_position);
- error(e.start_position,"Real/Formal argument mismatch (3).");
- end;
- -- For automatic conversion Expanded <-> Reference :
- at := at.run_type;
- ft := ft.run_type;
- if ft.is_expanded then
- if at.is_expanded then
- -- Expanded into Expanded.
- else
- -- Reference into Expanded.
- ft.used_as_reference;
- end;
- elseif at.is_expanded then
- -- Expanded into Reference.
- at.used_as_reference;
- else
- -- Reference into Reference.
- end;
- i := i - 1;
- end;
- end;
-
- to_runnable(ct: TYPE): like Current is
- require
- ct.run_type = ct
- local
- i: INTEGER;
- e1, e2: EXPRESSION;
- do
- if current_type = Void then
- current_type := ct;
- from
- i := list.upper;
- until
- i = 0
- loop
- e1 := list.item(i);
- e2 := e1.to_runnable(current_type);
- if e2 = Void then
- error(e1.start_position,"Bad expression.");
- elseif e1 /= e2 then
- list.put(e2,i);
- end;
- i := i - 1;
- end;
- if nb_errors = 0 then
- Result := Current;
- end;
- elseif ct.run_class = run_class then -- *** C'est POSSIBLE ???? ****
- Result := Current;
- else
- !!Result.make(list.twin);
- Result := Result.to_runnable(ct);
- end;
- end;
-
- afd_check is
- require
- current_type /= Void
- local
- i: INTEGER;
- do
- from
- i := list.upper;
- until
- i = 0
- loop
- list.item(i).afd_check;
- i := i - 1;
- end;
- end;
-
- compile_to_c(fal: FORMAL_ARG_LIST) is
- -- Produce C code for all expressions of the list.
- require
- cpp.on_c;
- count = fal.count
- local
- i, up: INTEGER;
- do
- from
- i := 1;
- up := count;
- until
- i > up
- loop
- compile_to_c_ith(fal,i);
- i := i + 1;
- if i <= up then
- cpp.put_character(',');
- end;
- end;
- ensure
- cpp.on_c
- end;
-
- compile_to_c_ith(fal: FORMAL_ARG_LIST; index: INTEGER) is
- -- Produce C code for expression `index'.
- require
- cpp.on_c;
- count = fal.count;
- 1 <= index;
- index <= count
- local
- e: EXPRESSION;
- ft: TYPE;
- do
- e := expression(index);
- ft := fal.type(index).run_type;
- e.mapping_c_arg(ft);
- ensure
- cpp.on_c
- end;
-
- compile_to_c_old is
- local
- i: INTEGER;
- do
- if list /= Void then
- from
- i := 1;
- until
- i > list.upper
- loop
- list.item(i).compile_to_c_old;
- i := i + 1;
- end;
- end;
- end;
-
- compile_to_jvm_old is
- local
- i: INTEGER;
- do
- if list /= Void then
- from
- i := 1;
- until
- i > list.upper
- loop
- list.item(i).compile_to_jvm_old;
- i := i + 1;
- end;
- end;
- end;
-
- compile_to_jvm(fal: FORMAL_ARG_LIST): INTEGER is
- require
- count = fal.count
- local
- i, up: INTEGER;
- do
- from
- i := 1;
- up := count;
- until
- i > up
- loop
- Result := Result + compile_to_jvm_ith(fal,i);
- i := i + 1;
- end;
- end;
-
- compile_to_jvm_ith(fal: FORMAL_ARG_LIST; index: INTEGER): INTEGER is
- require
- count = fal.count;
- 1 <= index;
- index <= count
- local
- e: EXPRESSION;
- ft: TYPE;
- do
- e := expression(index);
- ft := fal.type(index).run_type;
- Result := e.compile_to_jvm_into(ft);
- end;
-
- use_current: BOOLEAN is
- local
- i: INTEGER;
- do
- from
- i := 1
- until
- i > count or else Result
- loop
- Result := expression(i).use_current;
- i := i + 1;
- end;
- end;
-
- is_pre_computable: BOOLEAN is
- local
- i: INTEGER;
- do
- from
- i := count;
- Result := true;
- until
- not Result or else i = 0
- loop
- Result := expression(i).is_pre_computable;
- i := i - 1;
- end;
- end;
-
- pretty_print is
- local
- i: INTEGER;
- do
- fmt.put_character('(');
- from
- i := 1;
- until
- i > count
- loop
- expression(i).pretty_print;
- i := i + 1;
- if i <= count then
- fmt.put_character(',');
- end;
- end;
- fmt.put_character(')');
- end;
-
- short is
- local
- i: INTEGER;
- do
- short_print.hook_or("op_eal","(");
- from
- i := 1;
- until
- i > count
- loop
- expression(i).short;
- i := i + 1;
- if i <= count then
- short_print.hook_or("eal_sep",",");
- end;
- end;
- short_print.hook_or("cl_eal",")");
- end;
-
- is_static: BOOLEAN is
- -- Is true when only `is_static' expression are used.
- local
- i: INTEGER;
- do
- from
- Result := true;
- i := list.upper;
- until
- not Result or else i = 0
- loop
- Result := expression(i).is_static;
- i := i - 1;
- end;
- end;
-
- can_be_dropped: BOOLEAN is
- -- Is true when only `can_be_dropped' expression are used.
- local
- i: INTEGER;
- do
- from
- Result := true;
- i := list.upper;
- until
- not Result or else i = 0
- loop
- Result := expression(i).can_be_dropped;
- i := i - 1;
- end;
- end;
-
- feature {RUN_FEATURE_3,RUN_FEATURE_4}
-
- isa_dca_inline(relay_rf, rf: RUN_FEATURE): BOOLEAN is
- -- Assume `rf' is inside `relay_rf'.
- require
- relay_rf /= Void;
- rf /= Void
- local
- relay_args, args: FORMAL_ARG_LIST;
- e: EXPRESSION;
- i, r: INTEGER;
- do
- relay_args := relay_rf.arguments;
- args := rf.arguments;
- from
- Result := true;
- i := list.upper;
- isa_dca_inline_memory.force(false,i);
- isa_dca_inline_memory.clear_all;
- until
- not Result or else i = 0
- loop
- e := list.item(i);
- r := e.isa_dca_inline_argument;
- inspect
- r
- when 0 then
- Result := false;
- when -1 then
- if args.type(i).is_expanded then
- Result := e.result_type.is_expanded;
- else
- Result := e.result_type.is_reference;
- end;
- else
- check
- r > 0
- end;
- isa_dca_inline_memory.put(true,r);
- if relay_args.type(r).is_reference then
- if args.type(i).is_reference then
- Result := e.result_type.is_reference;
- else
- Result := false;
- end;
- elseif args.type(i).is_expanded then
- Result := e.result_type.is_expanded;
- else
- Result := false;
- end;
- end;
- i := i - 1;
- end;
- if Result then
- -- No arguments are lost :
- from
- i := relay_rf.arg_count;
- until
- not Result or else i = 0
- loop
- Result := isa_dca_inline_memory.item(i);
- i := i - 1;
- end;
- end;
- end;
-
- feature {NONE}
-
- isa_dca_inline_memory: ARRAY[BOOLEAN] is
- once
- !!Result.make(1,2);
- end;
-
- feature {C_PRETTY_PRINTER}
-
- dca_inline(fal: FORMAL_ARG_LIST) is
- require
- fal /= Void
- local
- i, up: INTEGER;
- do
- from
- up := list.upper;
- i := 1;
- until
- i > up
- loop
- dca_inline_ith(fal,i);
- i := i + 1;
- if i <= up then
- cpp.put_character(',');
- end;
- end;
- end;
-
- dca_inline_ith(fal: FORMAL_ARG_LIST; index: INTEGER) is
- require
- fal /= Void;
- index <= count
- local
- e: EXPRESSION;
- ft: TYPE;
- do
- e := expression(index);
- ft := fal.type(index).run_type;
- e.dca_inline_argument(ft);
- end;
-
- feature {NONE}
-
- is_like_argument(e: EXPRESSION; at, ft: TYPE): BOOLEAN is
- local
- tla: TYPE_LIKE_ARGUMENT;
- ot: TYPE;
- do
- tla ?= ft;
- if tla /= Void then
- Result := true;
- ot := expression(tla.rank).result_type;
- if not at.run_type.is_a(ot.run_type) then
- eh.add_position(e.start_position);
- error(ft.start_position," It is not Like <argument>.");
- end;
- end;
- end;
-
- feature {NONE}
-
- em1: STRING is " It is not Like Current.";
- em2: STRING is "Bad number of arguments.";
-
- invariant
-
- count > 0;
-
- list.lower = 1
-
- end -- EFFECTIVE_ARG_LIST
-
-